import { K8SResourceType, KVString, OperateFunction } from "yam-types"
import { Configuration } from "../types.d"
import { patchVolumeAndEnv } from "./util"

const configOperator: OperateFunction<Configuration> = async (plan, diff) => {
  const workload = plan.data.workloadName
  for (const item of diff.currentItems) {
    // configMap should be isolated by application, use workload name as prefix
    const cfgName = workload + "-" + item.name

    if (item.from) {
      const configMapData = {} as KVString
      for (const confPath of item.from) {
        const configData = await plan.renderTemplate(confPath, false)
        // avoid mount errors while using multiple level config,
        // eg: my-conf/~{ some.param }/app.config.yaml => mount as 'app.config.yaml'
        const tailingFilePath = confPath.substring(confPath.lastIndexOf('/') + 1)
        if (confPath.indexOf('/') !== -1) {
          plan.log.info(`config file path '${confPath}' will be flatted to '${tailingFilePath}'.`)
        }
        configMapData[tailingFilePath] = configData
        plan.log.debug(`config '${item.name}' rendered from '${confPath}', value is:\n${configData}`)
      }

      plan.action(async (ctx) => {
        try {
          // save configMap at apply stage
          await ctx.k8sClient.saveConf({
            name: cfgName,
            data: configMapData
          })
          // patch deployment/statefulset yaml object
          patchVolumeAndEnv(ctx, item, plan, cfgName, "configMap")
        } catch (e) {
          ctx.log.error(`sync-configMap '${cfgName}' failed: ${e.message}`)
          throw e
        }
      }, `sync-configMap:${item.name}`)
    }
  }

  // remove deleted configMap if deletedItems found
  for (const deletedItem of diff.deletedItems) {
    plan.action(async (ctx) => {
      await ctx.k8sClient.delete({
        name: deletedItem.name,
        namespace: plan.data.namespace,
        kind: K8SResourceType.ConfigMap
      })
      ctx.log.info(`configMap ${deletedItem.name} has been deleted from cluster`)
    }, `delete-configMap:${deletedItem.name}`)
  }

}


export default configOperator